import json
import os
import random
import threading
import time
import traceback

from urllib3.exceptions import MaxRetryError

from bot.bing_bot import NewbingBot
from bot.openai_bot import OpenAIBot
from browser.edge import EdgeDriver
from conf.config import logger, sem, BASE_DIR
from utils.laod_data import load_excel_sheet
from utils.output_file import output_json, output_html


def load_title_list():
    excel_file_path = os.path.join(BASE_DIR, "data.xlsx")
    sheet_name = "TitleList"
    data = load_excel_sheet(excel_file_path, sheet_name)

    title_list = list()
    for row in data[1:]:
        if not any(row):  # 空行
            continue
        title_list.append({"filename": row[0], "title": row[1]})

    return title_list


def generate_article_by_openai(title, filename):
    session_id = filename
    question_list = [
        f"写一篇攻略；标题为{title}；要求正文大于600-800字；要求不少于三段，每段起一个小标题",
        f"为以上攻略写一个200字以内的摘要，并给出2-3个关键词"
    ]

    with sem:
        try:
            openai_bot = OpenAIBot(session_id=filename)

            # 进行多轮对话
            answer_list = list()
            for index, value in enumerate(question_list):
                answer = openai_bot.reply(question=value, session_round=index)
                answer_list.append(answer)

            logger.info(f"{answer_list}")
        except Exception:
            error_str = traceback.format_exc()
            logger.error(error_str)


def generate_article_by_newbing(title, filename):
    """
    生成文章
    :param title: 标题
    :param filename: 文件名
    :return:
    """
    query_list = [
        f"写一篇攻略；标题为{title}；要求正文大于600-800字；要求不少于三段，每段起一个小标题",
        f"继续",
        f"为以上攻略写一个200字以内的摘要，并给出2-3个关键词"
    ]

    browser = EdgeDriver().browser
    try:
        newbing_bot = NewbingBot(browser)

        # 第一轮会话
        content1, content1_footer = newbing_bot.reply(query=query_list[0])

        # 第二轮会话
        content2, content2_footer = newbing_bot.reply(query=query_list[1])

        # 第三轮会话
        content3, content3_footer = newbing_bot.reply(query=query_list[2])

        data = {
            "id": filename,
            "title": title,
            "content1": content1, "content1_footer": content1_footer,
            "content2": content2, "content2_footer": content2_footer,
            "abstract_and_keywords": content3, "abstract_and_keywords_footer": content3_footer,
        }

        # 输出到html文件
        html = output_html(
            template_file_name="template_article.html",
            output_full_path=os.path.join(BASE_DIR, f"output/{filename}.html"),
            data=data
        )

        # 输出到json(中文为不可读的Unicode编码)
        output_json(
            output_full_path=os.path.join(BASE_DIR, f"output/{filename}.json"),
            data=data,
            ensure_ascii=True
        )
    except MaxRetryError:
        raise Exception("网络异常，超过最大重试次数，可能是未开启代理或其他原因")
    except Exception:
        error_str = traceback.format_exc()
        logger.error(error_str)
    finally:
        browser.quit()


def writing_by_newbing():
    """
    使用newbing写作
    :return:
    """
    title_list = load_title_list()
    logger.info(f"加载的标题列表：{title_list}")

    for item in title_list:
        if item["title"] and item["filename"]:
            generate_article_by_newbing(title=item["title"], filename=f'{item["filename"]}')
            time.sleep(random.uniform(3, 5))


def writing_by_openai():
    """
    使用openai写作
    :return:
    """
    title_list = load_title_list()
    logger.info(f"加载的标题列表：{title_list}")
    for item in title_list:
        if item["title"] and item["filename"]:
            thread = threading.Thread(target=generate_article_by_openai, args=(item["title"], item["filename"], ))
            thread.setDaemon(False)

            thread.start()
            logger.info(f"{thread.name} 已启动")

            time.sleep(random.uniform(3, 5))


def main():
    generate_article_by_openai(title="重庆公积金提取要求", filename="123456")


if __name__ == '__main__':
    main()
